# fetcher.rb
# Copyright (c) 2009 Alex Wilson
# Licensed under the MIT license (see LICENSE in the distribution root dir)

require "rubygems"
require "selenium/client"
require "tempfile"

module Timetable

# Fetches timetable data from mySI-net
class TimetableFetcher
  # The source XML downloaded from the timetable webpage
	attr_reader :srcs

	@@fetchers_active = Array.new
	@@fetchers_mutex = Mutex.new

	def initialize(courses)
		@courses = courses
		@srcs = Hash.new
	end
	
	# Connect to mySI-net using Selenium and fetch the timetable data. 
	def fetch
		waiting = true
		while waiting
			@@fetchers_mutex.synchronize do 
				waiting = (@@fetchers_active.size > 2) 
				@@fetchers_active << self if not waiting
			end
			sleep 1
		end
		
		fetch_blocks = []
		courses = @courses
		while courses.size > 2
			block,courses = courses.separate(1)
			fetch_blocks << block
		end
		fetch_blocks << courses
		
		begin
			fetch_blocks.each do |block|
			@browser = Selenium::Client::Driver.new("localhost", 4444, "*chrome", "https://www.sinet.uq.edu.au", 10000)
			#puts "- Logging into mySI-net..."
			@browser.start_new_browser_session
			block.each do |course|
				#puts "- Fetching timetable for #{course}..."
				@browser.open "/psp/ps/EMPLOYEE/HRMS/h/?tab=UQ_GENERAL"
			
				@browser.click "link=Course & Timetable Info", :wait_for => :page
				@browser.wait_for_pop_up "_parent", 30000
				@browser.select_frame "TargetContent"
				@browser.type "UQ_DRV_CRSE_SRC_UQ_SUBJECT_SRCH", course
				@browser.click "UQ_DRV_TT_GUEST_UQ_SEARCH_PB", :wait_for => :page
				
				# check for the internal one
				n = 0
				n += 1 while @browser.get_text("//table[@id='UQ_DRV_TT_GUEST$scrolli$0']/tbody/tr[#{n+2}]/td[6]/span") != "Internal"
				
				@browser.click "UQ_DRV_TT_GUEST$selm$#{n}$$0"
				@browser.click "UQ_DRV_TT_GUEST_UQ_NEXT_BUTTON$0", :wait_for => :page
				@browser.select_window "name=TargetContent"
				
				@srcs[course] = @browser.get_html_source()
				
				sleep 2
			end
			end
			
			:success
		ensure
			@browser.close_current_browser_session
		end
		@@fetchers_mutex.synchronize do
			@@fetchers_active.delete(self)
		end
	end
	
	# Tidy the raw HTML data using 'tidy', to make it into valid parseable XML.
	def tidy
		#puts "- Tidying..."
		@srcs.each do |key, src|
			tf = Tempfile.new "sinet-tidy"
			tf.write src
			tf.close
			
			`tidy -asxml -m -c -q #{tf.path} > /dev/null 2> /dev/null`
			
			tf.open
			@srcs[key] = tf.read
			tf.close
		end
		
		:success
	end
end

end



